package com.teen9g.infoplatformserver.service.impl;

import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.teen9g.constant.CategoryConstant;
import com.teen9g.constant.CommentConstant;
import com.teen9g.context.BaseContext;
import com.teen9g.dto.CommentDTO;
import com.teen9g.entity.Comment;
import com.teen9g.entity.CommentLike;
import com.teen9g.infoplatformserver.mapper.*;
import com.teen9g.infoplatformserver.service.CommentService;
import com.teen9g.vo.CommentVO;
import com.teen9g.vo.NoReplyCommentVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private CanteenShopMapper canteenShopMapper;

    @Autowired
    private PlaygroundMapper playgroundMapper;

    @Autowired
    private TeachingBuildingMapper teachingBuildingMapper;

    @Autowired
    private MaimaiChunithmMapper maimaiChunithmMapper;

    /**
     * 发布评论
     *
     * @param commentDTO 评论内容
     * @return 返回发布结果
     */
    @Override
    public String publishComment(CommentDTO commentDTO) {
        //先检验评论内容是否有敏感词
        if (SensitiveWordHelper.contains(commentDTO.getComment())) {
            return CommentConstant.MSG_SENSITIVE_WORDS;
        }
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentDTO, comment);

        //TODO 暂时设置IP为天津
        comment.setIpAddress(CommentConstant.IP_TEST);
        comment.setLikeCount(0);
        comment.setReplyCount(0);
        comment.setUserName(BaseContext.getCurrentUser());
        comment.setUserId(BaseContext.getCurrentUserId());
        comment.setStatus(CommentConstant.STATUS_PUBLISHED);
        comment.setCommentCreateTime(LocalDateTime.now());
        if (commentMapper.insert(comment) > 0) {
            //根据relatedCategory和relatedId更新对应的评论数 +1
            String relatedCategory = commentDTO.getRelatedCategory();
            Integer relatedId = commentDTO.getRelatedId();
            updateCommentCount(relatedCategory, relatedId, 1);
            return CommentConstant.PUBLISH_SUCCESS;
        } else {
            return CommentConstant.PUBLISH_FAILED;
        }
    }

    /**
     * 发布回复
     *
     * @param commentDTO 评论内容
     * @return 返回发布结果
     */
    @Override
    public String publishReply(CommentDTO commentDTO) {
        //先检验评论内容是否有敏感词
        if (SensitiveWordHelper.contains(commentDTO.getComment())) {
            return CommentConstant.MSG_SENSITIVE_WORDS;
        }
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentDTO, comment);

        //TODO 暂时设置IP为天津
        comment.setIpAddress(CommentConstant.IP_TEST);
        comment.setLikeCount(0);
        comment.setReplyCount(0);
        comment.setUserName(BaseContext.getCurrentUser());
        comment.setUserId(BaseContext.getCurrentUserId());
        comment.setStatus(CommentConstant.STATUS_PUBLISHED);
        comment.setRootCommentId(commentDTO.getRootCommentId());
        comment.setCommentCreateTime(LocalDateTime.now());
        if (commentMapper.insert(comment) > 0) {
            //更新父评论的回复数
            commentMapper.updateReplyCount(commentDTO.getRootCommentId(), 1);
            //根据relatedCategory和relatedId更新对应的评论数 +1
            String relatedCategory = commentDTO.getRelatedCategory();
            Integer relatedId = commentDTO.getRelatedId();
            updateCommentCount(relatedCategory, relatedId, 1);
            return CommentConstant.PUBLISH_SUCCESS;
        } else {
            return CommentConstant.PUBLISH_FAILED;
        }
    }

    /**
     * 删除评论
     *
     * @param commentId 评论ID
     * @return 返回删除结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String deleteComment(Integer commentId) {
        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            return CommentConstant.DELETE_NOT_FOUND;
        }
        if (!comment.getUserId().equals(BaseContext.getCurrentUserId())) {
            return CommentConstant.DELETE_NOT_AUTHOR;
        }

        try {
            if (comment.getRootCommentId() != null) {
                // 如果是子评论，删除自身
                int deleteCount = commentMapper.deleteById(commentId);
                //删除后需要更新对应条目的评论数
                if (deleteCount > 0) {
                    String relatedCategory = comment.getRelatedCategory();
                    Integer relatedId = comment.getRelatedId();
                    updateCommentCount(relatedCategory, relatedId, -deleteCount);
                }
            } else {
                // 如果是父评论，删除自身和所有子评论
                int deleteSubCount = commentMapper.deleteRelatedSubComment(commentId);
                int deleteSelfCount = commentMapper.deleteById(commentId);
                //删除后需要更新对应条目的评论数
                if (deleteSelfCount + deleteSubCount > 0) {
                    String relatedCategory = comment.getRelatedCategory();
                    Integer relatedId = comment.getRelatedId();
                    updateCommentCount(relatedCategory, relatedId, (-deleteSelfCount - deleteSubCount));
                }
            }
            return CommentConstant.DELETE_SUCCESS;
        } catch (DataAccessException dae) {
            log.error("数据库操作异常，评论ID: {}, 用户ID: {}", commentId, BaseContext.getCurrentUserId());
            return CommentConstant.DELETE_FAILED;
        } catch (Exception e) {
            log.error("删除评论时发生未知异常，评论ID: {}, 用户ID: {}", commentId, BaseContext.getCurrentUserId());
            return CommentConstant.DELETE_FAILED;
        }
    }


    @Override
    public PageInfo<CommentVO> getCommentTree
            (Integer relatedId, String relatedCategory,
             Integer pageNum, Integer pageSize, String orderBy) {
        //1. 构建排序字段和顺序
        String orderByClause = getOrderByClause(orderBy);
        Integer total = commentMapper.selectTotal(relatedId, relatedCategory);
        //2. 开始分页
        PageHelper.startPage(pageNum, pageSize).setOrderBy(orderByClause);
        // 3. 查询分页的父评论
        List<NoReplyCommentVO> noReplyCommentVOList =
                commentMapper.selectNoReplyComment(relatedCategory, relatedId);
        // 4. 将父评论转换为 CommentVO 并加载子评论
        //先构建新的CommentVO,再将noReplyCommentVO中的值复制过去,然后加载子评论
        List<CommentVO> commentVOList = new ArrayList<>();
        for (NoReplyCommentVO noReplyComment : noReplyCommentVOList) {
            CommentVO commentVO = new CommentVO();
            BeanUtils.copyProperties(noReplyComment, commentVO);
            //加载子评论
            List<NoReplyCommentVO> replyCommentList =
                    commentMapper.selectReplyComment(relatedCategory, relatedId, commentVO.getCommentId());
            commentVO.setReplyComments(replyCommentList);
            commentVOList.add(commentVO);
        }
        // 5. 获取分页信息
        PageInfo<CommentVO> commentVOPageInfo = new PageInfo<>(commentVOList);
        commentVOPageInfo.setTotal(total);
        return commentVOPageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String likeChange(Integer commentId) {
        //判断该评论是否存在
        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            return CommentConstant.CHANGE_LIKE_NOT_FOUND;
        }
        Integer userId = BaseContext.getCurrentUserId();
        //查询是否有点赞记录
        Integer track = commentMapper.selectLikeTrack(userId, commentId);
        if (track != 0) {
            //取消点赞
            commentMapper.deleteLikeTrack(userId, commentId);
            //对应的评论点赞数-1
            commentMapper.updateLikeCount(commentId, -1);
            return CommentConstant.DISLIKE_SUCCESS;
        } else {
            //插入一条点赞记录
            CommentLike commentLike = CommentLike.builder()
                    .commentId(commentId)
                    .userId(userId)
                    .createdAt(LocalDateTime.now())
                    .build();
            commentMapper.insertLikeTrack(commentLike);
            //对应的评论点赞数+1
            commentMapper.updateLikeCount(commentId, 1);
            return CommentConstant.LIKE_SUCCESS;
        }
    }

    @Override
    public Integer checkLike(Integer commentId, Integer userId) {
        return commentMapper.selectLikeTrack(userId, commentId);
    }


    //评论分页查询辅助方法：根据 orderBy 参数生成排序语句
    private String getOrderByClause(String orderBy) {
        // 根据 orderBy 参数生成排序语句
        switch (orderBy.toLowerCase()) {
            case CommentConstant.PAGE_ORDER_BY_LIKE:
                return "like_count DESC"; // 按点赞数递减排序
            case CommentConstant.PAGE_ORDER_BY_TIME:
                return "comment_create_time DESC"; // 按创建时间从近到远排序
            default:
                return "like_count DESC"; // 默认按点赞数排序
        }
    }

    //根据评论所处的类型的ID更新对应的评论数
    private void updateCommentCount(String relatedCategory, Integer relatedId, Integer updateCount) {
        switch (relatedCategory) {
            case CategoryConstant.CANTEEN_SHOP:
                canteenShopMapper.updateCommentCount(relatedId, updateCount);
                break;
            case CategoryConstant.PLAYGROUND:
                playgroundMapper.updateCommentCount(relatedId, updateCount);
                break;
            case CategoryConstant.TEACHING_BUILDING:
                teachingBuildingMapper.updateCommentCount(relatedId, updateCount);
                break;
            case CategoryConstant.MAIMAI_CHUNITHM:
                maimaiChunithmMapper.updateCommentCount(relatedId, updateCount);
                break;
        }
    }

}
